/*******************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Co.,Ltd.        */
/*                                                                 */
/*  NAME      = ora_NUMBER.c                                       */
/*  NOTE      =                                                    */
/*  DATE      = 2014/11/07 by songbb                               */
/*******************************************************************/

#include <stdio.h>
#include <memory.h>
#include <string.h>
#include <stdlib.h>
#include <netinet/in.h>
#include <float.h>
#include <ctype.h>

#include "frcomm.h"
#include "frstr.h"
#include "frmem.h"
#include "frlog.h"

#include "../../ora_core.h"
#include "../../comm/ora_comm.h"
#include "../../comm/ora_util.h"
#include "ora_NUMBER.h"
#include "ora_LnxLibThin.h"

FR_STATIC int DBLMAX = 128;

int ora_NUMBER_isZero(char *p_data, unsigned int ui_len)
{
    if (p_data[0] == -128 && ui_len == 1)
        return FR_SUCC;
    else
        return FR_FAIL;
}

int ora_NUMBER_isPosInf(char *p_data, unsigned int ui_len)
{
    if (ui_len == 2 && p_data[0] == -1 && p_data[1] == 101)
        return FR_SUCC;
    else
        return FR_FAIL;
}

int ora_NUMBER_isNegInf(char *p_data, unsigned int ui_len)
{
    if (p_data[0] == 0 && ui_len == 1)
        return FR_SUCC;
    else
        return FR_FAIL;
}

int ora_NUMBER_isInf(char *p_data, unsigned int ui_len)
{
    if ((ui_len == 2 && p_data[0] == -1 && p_data[1] == 101) || (p_data[0] == 0 && ui_len == 1))
        return FR_SUCC;
    else
        return FR_FAIL;
}

int ora_NUMBER_isPositive(char *p_data)
{
    if ((p_data[0] & 0xffffff80) != 0)
        return FR_SUCC;
    else
        return FR_FAIL;
}

int ora_NUMBER_makeZero(char **pp_out
                        , int *p_i_out_len)
{
    char *p_b = NULL;
    if ((p_b = (char *) frmalloc(sizeof(char))) == NULL)
    {
        ORA_MALLOCK_ERR;
        return FR_FAIL;
    }
    p_b[0] = -128;
    *pp_out = p_b;
    *p_i_out_len = 1;
    return FR_SUCC;
}

int ora_NUMBER_makeNegInf(char **pp_out
                        , int *p_i_out_len)
{
    char *p_b = NULL;
    if ((p_b = (char *) frmalloc(sizeof(char))) == NULL)
    {
        ORA_MALLOCK_ERR;
        return FR_FAIL;
    }
    p_b[0] = 0;
    *pp_out = p_b;
    *p_i_out_len = 1;
    return FR_SUCC;
}

int ora_NUMBER_makePosInf(char **pp_out
                        , int *p_i_out_len)
{
    char *p_b = NULL;
    if ((p_b = (char *) frmalloc(2 * sizeof(char))) == NULL)
    {
        ORA_MALLOCK_ERR;
        return FR_FAIL;
    }
    p_b[0] = -1;
    p_b[1] = 101;
    *pp_out = p_b;
    *p_i_out_len = 2;
    return FR_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析数字类型，所有的数字均以字符串类型输出数据
*  ARGS     :  *p_payload                           (数据内容)
*           :  ui_payload_len                       (数据长度)
*           :  **pp_out                             (解析后的字符串内容)
*           :  *p_i_out_len                         (解析后的字符串长度)
*  RTN      :  0                                    (FR_SUCC)
*              1                                    (FR_FAIL)
*  NOTE     :
*******************************************************************************/
int ora_NUMBER_toChar(char *p_payload
                    , unsigned int ui_payload_len
                    , char **pp_out
                    , int *p_i_out_len)
{
    char *p_out = NULL;
    int i_loop = 0;
    char *p_orig_out = NULL;
    int i_str_len = 0;
    int i_space_idx = 0;
    int i_space_prefix = 1;
    int i_find_dot = 0;
    int i_dot_idx = 0;
    int i_last_valid_number_idx = DBLMAX;

    if ((p_out = (char *) frmalloc(APM_ORA_NUMBER_STR_MAXLEN * sizeof(char))) == NULL)
    {
        ORA_PRINT_EMERG("can not malloc memory\n");
        ORA_FRLOG_ERROR("can not malloc memory");
        goto error;
    }

    if (ora_NUMBER_isZero(p_payload, ui_payload_len) == FR_SUCC)
    {
        snprintf(p_out, APM_ORA_NUMBER_STR_MAXLEN, "%d", 0);
        goto success;
    }
    if (ora_NUMBER_isPosInf(p_payload, ui_payload_len) == FR_SUCC)
    {
        snprintf(p_out, APM_ORA_NUMBER_STR_MAXLEN, "%d", 1);
        goto success;
    }
    if (ora_NUMBER_isNegInf(p_payload, ui_payload_len) == FR_SUCC)
    {
        snprintf(p_out, APM_ORA_NUMBER_STR_MAXLEN, "%d", -1);
        goto success;
    }

    if (ora_lnxnuc(p_payload, ui_payload_len, DBLMAX, &p_orig_out) != FR_SUCC)
        goto error;

    // 除去前置的空格
    for (i_loop = 0; i_loop < DBLMAX; i_loop++)
    {
        if (i_space_prefix && isspace(p_orig_out[i_loop]))
            i_space_idx++;
        else
        {
            i_space_prefix = 0;
            if (!i_find_dot && p_orig_out[i_loop] == '.')
            {
                i_find_dot = 1;
                i_dot_idx = i_loop;
            }
        }
    }
    // 如果有小数点，除去小数点后无效的数字0
    if (i_find_dot)
    {
        for (i_loop = DBLMAX - 1; i_loop > i_dot_idx; i_loop--)
        {
            if (isdigit(p_orig_out[i_loop]) && p_orig_out[i_loop] != '0')
            {
                i_last_valid_number_idx = i_loop;
                break;
            }
            if ((i_loop - 1) == i_dot_idx || p_orig_out[i_loop] == '.')
                i_last_valid_number_idx = i_loop - 2;
        }
        i_str_len = (DBLMAX - i_space_idx) - (DBLMAX - i_last_valid_number_idx - 1);
    }
    else
        i_str_len = DBLMAX - i_space_idx;

    memcpy(p_out, p_orig_out + i_space_idx, (size_t) i_str_len);
    p_out[i_str_len] = '\0';

success:
    *pp_out = p_out;
    *p_i_out_len = strlen(p_out);
    ora_free((void **) &p_orig_out);
    return FR_SUCC;
error:
    ora_free((void **) &p_orig_out);
    ora_free((void **) &p_out);
    return FR_FAIL;
}
